/**
 * @file   PacketParser.h
 * @author Djuro Drljaca (djurodrljaca@gmail.com)
 * @date   2013-03-10
 * @brief  DataBus Packet Parser.
 *
 * Copyright (C) 2013  Djuro Drljaca <djurodrljaca@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef LIBDATABUS_COMMON_PACKETPARSER_H
#define LIBDATABUS_COMMON_PACKETPARSER_H

#include <DataBus/Common/Common.h>
#include <DataBus/Common/Packet.h>
#include <DataBus/Common/PacketHeader.h>
#include <DataBus/Common/PacketPayload.h>
#include <QtCore/QList>

namespace DataBus
{
/**
 * @brief The PacketParser class
 */
class DATABUSSHARED_EXPORT PacketParser
{
public:
    /**
     * @brief Constructor for PacketParser
     */
    PacketParser();

    /**
     * @brief Initialize packet parser
     */
    void initialize();

    /**
     * @brief Checks if a packet is available
     *
     * @retval true     Packet is available
     * @retval false    Packet is not available
     */
    bool isPacketAvailable() const;

    /**
     * @brief Takes the received packet and starts the processing of received data for the next packet
     *
     * @return Received packet
     */
    Packet takePacket();

    /**
     * @brief Process received data
     *
     * @param data  New received data
     */
    void processReceivedData(const QByteArray &data);

private:
    /**
     * @brief Waits for start of packet frame
     *
     * @retval true     Waiting for more data
     * @retval false    Not waiting
     */
    bool waitForStartOfFrame();

    /**
     * @brief Reads packet header
     *
     * @retval true     Waiting for more data
     * @retval false    Not waiting
     */
    bool readPacketHeader();

    /**
     * @brief Reads packet payload
     *
     * @retval true     Waiting for more data
     * @retval false    Not waiting
     */
    bool readPacketPayload();

    /**
     * @brief Waits for end of packet frame
     *
     * @retval true     Waiting for more data
     * @retval false    Not waiting
     */
    bool waitForEndOfFrame();

    /**
     * @brief The State enum
     */
    enum State
    {
        State_WaitForStartOfFrame = 0,  /**< Waiting for start of frame (STX character) */
        State_ReadPacketHeader,         /**< Reading packet header */
        State_ReadPacketPayload,        /**< Reading packet payload */
        State_WaitForEndOfFrame         /**< Waiting for end of frame (ETX character) */
    };

    /**
     * @brief Packet list
     */
    QList<Packet> m_packetList;

    /**
     * @brief Packet header
     */
    PacketHeader m_packetHeader;

    /**
     * @brief Packet payload
     */
    PacketPayload m_packetPayload;

    /**
     * @brief Buffer for received data
     */
    QByteArray m_buffer;

    /**
     * @brief State of the parser (state machine state)
     */
    State m_state;
};
}

#endif // LIBDATABUS_COMMON_PACKETPARSER_H
